#include "../../include/Reactor/ProtocolParser.h"

using std::string;
using std::function;
using std::bind;
using std::shared_ptr;
using std::make_shared;
using std::endl;
using std::cout;

string ProtocolParser::serializeMessage(const Message& msg)
{
    int32_t nTag = htonl(msg.tag);
    int32_t nLength = htonl(msg.length);
    string result;
    result.append((const char*)&nTag, sizeof(nTag));
    result.append((const char*)&nLength, sizeof(nLength));
    result.append(msg.value);
    return result;
}

Message ProtocolParser::parseMessage(const string &data)
{
    Message msg;

    if(!isMessageComplete(data))
    {
        return msg;
    }
    int32_t nTag = 0;
    int32_t nLength = 0;

    memcpy(&nTag, data.c_str(), sizeof(nTag));
    memcpy(&nLength, data.c_str() + sizeof(nTag), sizeof(nLength));

    msg.tag = ntohl(nTag);
    msg.length = ntohl(nLength);

    msg.value.assign(data.c_str() + sizeof(nTag) + sizeof(nLength), msg.length);
    return msg;
}

bool ProtocolParser::isMessageComplete(const string &data)
{
    if(data.size() < 8)
    {
        cout << "长度错误1" << endl;
        return false;
    }

    int32_t length;
    memcpy(&length, data.c_str() + 4, sizeof(length));

    int32_t realLength = ntohl(length);

    if(data.size() < (size_t)realLength + 8)
    {
        cout << "长度错误2" << endl;
        return false;
    }
    return true;
}

MyTaskPtr ProtocolParser::makeTask(const Message& msg, const TcpConnectionPtr &con)
{
#ifdef DEBUG
    cout << "得到tag: " << msg.tag << endl;
#endif
    switch(msg.tag)
    {
    case KeyRecommand:
        return MyTask::createKeyRecommandTask(msg.value, con);
    case WebPageSearch:
        return MyTask::createWebPageSearchTask(msg.value, con);
    default:
        return MyTask::createErrorTask(msg.value, con);
    }
}